/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.control;

import org.zhiqim.kernel.model.interfaces.Openb;

/**
 * 同步isRunning控制器
 * 基类实现如下：
 * 1、不可重写的open/close方法
 * 2、线程管理（volatile的isRunning）
 * 
 * 子类操作如下：
 * 1、子类可提供open/close/isRunning操作前后的设置和清理实现
 *
 * @version v1.0.0 @author zouzhigang 2018-11-17 新建与整理
 */
public abstract class Running implements Openb
{
    private volatile boolean isRunning;
    
    /*************************************************************************/
    //子类实现的方法
    /*************************************************************************/
    
    /** 子类开启标志之前的可选操作 */
    protected boolean openBefore(){return true;}
    
    /** 子类关闭标志之后的可选操作 */
    protected void closeAfter(){}
    
    /*************************************************************************/
    //开启&关闭
    /*************************************************************************/
    
    @Override /** 开启 */
    public final synchronized boolean open()
    {
        if (isRunning)
            return false;
        
        //1.子类开启
        try{if (!openBefore()){return false;}}
        catch(Throwable e){return false;}
        
        //2.置状态为开启中
        isRunning = true;
        return true;
    }
    
    @Override /** 关闭 */
    public final synchronized void close()
    {
        if (!isRunning)
            return;
        
        //1.置状态为关闭中
        isRunning = false;
        
        //2.子类关闭（注意如果异常，状态已变调用也不会再执行关闭）
        try{closeAfter();}catch(Throwable e){}
    }
    
    /** 判断运行状态 */
    public final boolean isRunning()
    {
        return isRunning;
    }
}
